package com.example.demo.nio;

import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

import static com.example.demo.nio.ByteBufferUtil.debugAll;

public class TestByteBuffer {

    public static void main(String[] args) {

//        allocate();
//        allocateDirect();
//        mark();
        strToBf();

    }

    private static void strToBf() {

        /**
         *  字符串转为ByteBuffer
         */

        // 1、StandardCharsets
        ByteBuffer bf1 = StandardCharsets.UTF_8.encode("hi");
        // 2、Charset
        ByteBuffer bf2 = Charset.forName("utf-8").encode("hello");
        ByteBuffer bf3 = ByteBuffer.allocate(10);
        // 3、getBytes
        bf3.put("world".getBytes());
        // 4、wrap 1和2底层都是调用CharBuffer.wrap(str)方法
        ByteBuffer bf4 = ByteBuffer.wrap("xxxx".getBytes(StandardCharsets.UTF_8));
        debugAll(bf1);
        debugAll(bf2);
        debugAll(bf3);
        debugAll(bf4);

        /**
         * ByteBuffer转字符串
         */
        String s1 = StandardCharsets.UTF_8.decode(bf1).toString();
        String s2 = Charset.forName("utf-8").decode(bf2).toString();
        System.out.println(s1);
        System.out.println(s2);
    }

    private static void mark() {
        // 申请10个字节的堆空间，由jvm调度，效率较低
        ByteBuffer bf1 = ByteBuffer.allocate(10);
        bf1.put(new byte[]{'a','b','c','d'});
        bf1.flip();
        System.out.println((char) bf1.get());
        System.out.println((char) bf1.get());
        bf1.mark();
        System.out.println((char) bf1.get());
        System.out.println((char) bf1.get());
        bf1.reset();
        System.out.println((char) bf1.get());
        System.out.println((char) bf1.get());
    }

    private static void allocateDirect() {
        // 申请10个字节的直接空间，由os调度，效率较高，少了一次拷贝
        ByteBuffer bf2 = ByteBuffer.allocateDirect(10);

    }

    private static void allocate() {
        // 申请10个字节的堆空间，由jvm调度，效率较低
        ByteBuffer bf1 = ByteBuffer.allocate(10);

        bf1.put(new byte[]{'a','b','c','d'});
        debugAll(bf1);
        // 获取不到数据，因为get方法会使pos指针往后移动，此时pos为4
//        System.out.println("读取数据："+bf1.get());
        debugAll(bf1);
        System.out.println("读模式切换");
        // 切换到读模式，pos从0开始
        bf1.flip();
        System.out.println("读取数据："+bf1.get());

        debugAll(bf1);
        // 切换到写模式，未读取的元素会往前移
        System.out.println("写模式切换");
        bf1.compact();
        debugAll(bf1);
        System.out.println("000000000000000000000000");
        debugAll(bf1);
        bf1.put("e".getBytes(StandardCharsets.UTF_8));
        debugAll(bf1);

        System.out.println("rewind()");
        // rewind方法将pos设置为0
        bf1.rewind();
        debugAll(bf1);

        System.out.println((char)bf1.get());
        // 使用get(i)读取指定下标的数据
//        System.out.println(bf1.get(1));

        // 标记pos位置
        System.out.println("mark()");
        bf1.mark();
        debugAll(bf1);

        // 回到mark的位置
        System.out.println("reset()");
        bf1.reset();
        debugAll(bf1);
        System.out.println((char)bf1.get());
    }
}
